package modelo;

import java.math.BigDecimal;
import java.util.List;

import modelo.query.InvalidQueryException;
import modelo.reglas.Specificable;
import modelo.reglas.engine.BestSell;
import util.ProductUtils;

public class Venta extends Specificable {
	private OrdenDeCompra ordenDeCompra;

	private List<Oferta> ofertasProductosAplicada;
	private List<Oferta> ofertaVentaAplicada;
	private List<Cupon> cuponesPresentados;

	private BigDecimal precioFinal = BigDecimal.ZERO;
	private BigDecimal subtotal = BigDecimal.ZERO;
	private BigDecimal descuentos = BigDecimal.ZERO;
	private Cupon cuponGenerado;

	public Venta() {
	}

	public Venta(OrdenDeCompra oc, List<Oferta> ofertasProductoAplicar, List<Oferta> ofertasVentaAplicar, List<Cupon> cuponesAplicar,
			boolean generateCupon) {
		this.ordenDeCompra = oc;
		this.ofertasProductosAplicada = ofertasProductoAplicar;
		this.ofertaVentaAplicada = ofertasVentaAplicar;
		this.cuponesPresentados = cuponesAplicar;
		try {
			subtotal = ProductUtils.sumarTotalProductos(ordenDeCompra.getProductos()).setScale(2, BigDecimal.ROUND_HALF_UP);
			BigDecimal auxTotal = BestSell.calcularTotal(ordenDeCompra, ofertasProductosAplicada, ofertaVentaAplicada).setScale(2,
					BigDecimal.ROUND_HALF_UP);

			if (generateCupon) {
				BigDecimal auxDesc;
				if (subtotal.compareTo(auxTotal) > 0) {
					auxDesc = subtotal.subtract(auxTotal);
					cuponGenerado = new Cupon(Long.toString(oc.getFechaOrden().getTime()), oc.getFechaOrden(), auxDesc);
				}
				precioFinal = BestSell.applyCuponsDiscount(subtotal, BestSell.calculateTotalCupons(cuponesPresentados));

			} else {
				precioFinal = BestSell.applyCuponsDiscount(auxTotal, BestSell.calculateTotalCupons(cuponesPresentados));
			}

			if (subtotal.compareTo(precioFinal) > 0) {
				descuentos = subtotal.subtract(precioFinal);
			}

		} catch (InvalidQueryException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public int compareTo(Specificable o) {
		if (o instanceof Venta) {
			Venta p = (Venta) o;

			return ordenDeCompra.compareTo(p.ordenDeCompra);
		}
		return -1;
	}

	public List<Oferta> getOfertasProductosAplicada() {
		return ofertasProductosAplicada;
	}

	public List<Oferta> getOfertaVentaAplicada() {
		return ofertaVentaAplicada;
	}

	public OrdenDeCompra getOrdenDeCompra() {
		return ordenDeCompra;
	}

	public BigDecimal getPrecioFinal() {
		return precioFinal;
	}

	public BigDecimal getSubtotal() {
		return subtotal;
	}

	public BigDecimal getDescuentos() {
		return descuentos;
	}

	public Cupon getCuponGenerado() {
		return cuponGenerado;
	}
}
